package de.sp.games.snake12k.boxes;

import java.util.ArrayList;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;

import de.sp.games.snake12k.SUtil;

public class SnakeBox extends Box implements IBoxable
{

	private Image image;

	private boolean isUpPressed = false;
	private boolean isLeftPressed = false;
	private boolean isRightPressed = false;
	private boolean isDownPressed = false;
	private boolean keyPressed = false;

	private ArrayList<Box> boxList;

	Sound die = new Sound("ressource/die.wav");

	public SnakeBox(int x, int y, final int indexX, final int indexY, ArrayList<Box> boxList) throws SlickException
	{
		super(x, y, new Image("ressource/box_empty.jpg"), indexX, indexY);
		image = new Image("ressource/snake_tiles.png");
		image = image.getSubImage(0, 0, 16, 16);
		image.setFilter(Image.FILTER_NEAREST);
		isCollision = true;
		isChangeable = false;
		boxImage = image;
		this.boxList = boxList;
	}

	public void draw(Graphics g)
	{
		super.draw(g);
		if (SUtil.gameOver)
		{
			g.drawString("GAME OVER!", 400, 200);
		}
	}

	//TODO: Steuerung fuehlt sich noch leicht "merkwuerdig" an
	//schwer zu defininieren...
	@Override
	public void update(GameContainer gc, ArrayList<Box> boxList) throws SlickException
	{
		Input input = gc.getInput();
		this.boxList = boxList;

		if (input.isKeyPressed(Input.KEY_UP) && !isDownPressed && !keyPressed)
		{
			unPresseOther(SUtil.UP);
			image.setRotation(90);
			keyPressed = true;
			SUtil.startPlayedTime();
			input.clearKeyPressedRecord();
		}
		if (input.isKeyPressed(Input.KEY_LEFT) && !isRightPressed && !keyPressed)
		{
			unPresseOther(SUtil.LEFT);
			image.setRotation(360);
			keyPressed = true;
			SUtil.startPlayedTime();
			input.clearKeyPressedRecord();
		}
		if (input.isKeyPressed(Input.KEY_RIGHT) && !isLeftPressed && !keyPressed)
		{
			unPresseOther(SUtil.RIGHT);
			image.setRotation(180);
			keyPressed = true;
			SUtil.startPlayedTime();
			input.clearKeyPressedRecord();
		}
		if (input.isKeyPressed(Input.KEY_DOWN) && !isUpPressed && !keyPressed)
		{
			unPresseOther(SUtil.DOWN);
			image.setRotation(270);
			keyPressed = true;
			SUtil.startPlayedTime();
			input.clearKeyPressedRecord();
		}

		if (SUtil.isTimeMove())
		{
			keyPressed = false;
			snakeMove();
			if (SUtil.isPlayedTimerOn)
			{
				grow(SUtil.picUpGrowValue);
			}
			input.clearControlPressedRecord();
		}
	}

	private void snakeMove() throws SlickException
	{

		if (isUpPressed)
		{
			if (!checkCollisionY(+1))
			{
				y -= 16;
				indexY -= 1;
			}
		}
		if (isLeftPressed)
		{
			if (!checkCollisionX(+1))
			{
				x -= 16;
				indexX -= 1;
			}
		}
		if (isRightPressed)
		{
			if (!checkCollisionX(-1))
			{
				x += 16;
				indexX += 1;
			}
		}
		if (isDownPressed)
		{
			if (!checkCollisionY(-1))
			{
				y += 16;
				indexY += 1;
			}
		}
	}

	public void grow(final int growValue) throws SlickException
	{
		boxList.add(new SnakeBodyBox(SUtil.snakeDirection, this.getIndexX(), this.getIndexY(), this.boxList));
	}

	private void unPresseOther(final int direction)
	{
		switch (direction)
		{
		case SUtil.UP:
			isLeftPressed = false;
			isRightPressed = false;
			isDownPressed = false;
			isUpPressed = true;
			SUtil.snakeDirection = SUtil.UP;
			break;

		case SUtil.LEFT:
			isUpPressed = false;
			isRightPressed = false;
			isDownPressed = false;
			isLeftPressed = true;
			SUtil.snakeDirection = SUtil.LEFT;
			break;

		case SUtil.RIGHT:
			isLeftPressed = false;
			isUpPressed = false;
			isDownPressed = false;
			isRightPressed = true;
			SUtil.snakeDirection = SUtil.RIGHT;
			break;

		case SUtil.DOWN:
			isLeftPressed = false;
			isRightPressed = false;
			isUpPressed = false;
			isDownPressed = true;
			SUtil.snakeDirection = SUtil.DOWN;
			break;

		default:
			throw new IllegalArgumentException();
		}
	}

	// direction -> +1 Boxe above Snake 
	private boolean checkCollisionY(final int direction)
	{
		boolean collision = false;

		if (boxList.get(SUtil.getBoxArrayIndex(indexX, indexY - direction, boxList)).isCollision())
		{
			SUtil.gameOver = true;
			collision = true;
			die.play();
		}
		return collision;
	}

	// TODO: doppelt code ...-> SUtil.checkCollision einbauen!
	private boolean checkCollisionX(final int direction)
	{
		boolean collision = false;

		if (boxList.get(SUtil.getBoxArrayIndex(indexX - direction, indexY, boxList)).isCollision())
		{
			SUtil.gameOver = true;
			collision = true;
			die.play();
		}
		return collision;
	}

}
